use std::{sync::Arc, time::Duration};

use crate::{
    db::{add_ad, add_gov, add_hot, in_ad, in_gov, in_hot, updata_hot},
    hot::{Ad, Gov, Hot},
    utils::{clean_old_logs, get_current_timestamp, get_hot_webapi, handle_res_json},
};
use sqlx::PgPool;
use tokio::time::interval;
use tracing::{debug, error, info, warn};

pub async fn start_hot_search_collection() {
    let hot_search_interval = Duration::from_secs(30); // 30 sec
    let hot_search_update = Duration::from_secs(30 * 60); // 20 minutes,强制更新
    let ad_clear = Duration::from_secs(60 * 60); //1h,清除多余
    let gov_clear = Duration::from_secs(24 * 60 * 60); //1day清空
    let log_cleaning_interval = Duration::from_secs(24 * 60 * 60); // 1 day
    let log_dir = "log_files";
    let max_age_days = 30;
    // Task to collect hot searches
    tokio::spawn(async move {
        let mut interval = interval(hot_search_interval);
        // #region 初始化
        //postgres://postgres:jxl998124@49.235.100.142:5555/ubuntudb
        //postgres://postgres:jxl998124@localhost:5555/ubuntudb
        let pool = Arc::new(
            match PgPool::connect("postgres://postgres:jxl998124@49.235.100.142:5555/ubuntudb")
                .await
            {
                Ok(pool) => pool,
                Err(_) => panic!("连接错误"),
            },
        );
        // 广告
        let mut ad_list: Vec<Ad> = Vec::new();
        // 政务
        let mut gov_list: Vec<Gov> = Vec::new();
        // 热搜
        let mut hot_list: Vec<Hot> = Vec::new();

        // let hot_list = Arc::new(Mutex::new(hot_list));
        let ad_count_max = ad_clear.as_secs() / hot_search_interval.as_secs();
        let gov_count_max = gov_clear.as_secs() / hot_search_interval.as_secs();
        let hot_count_max = hot_search_update.as_secs() / hot_search_interval.as_secs();
        let mut ad_count = 0;
        let mut gov_count = 0;
        let mut hot_count = 0;

        // #endregion
        loop {
            interval.tick().await;
            let v = get_hot_webapi().await;
            // let mut new_hot_list: Vec<Hot> = Vec::new();
            // let mut new_gov_list: Vec<Gov> = Vec::new();
            // let mut new_ad_list: Vec<Ad> = Vec::new();
            let (new_ad_list, new_gov_list, new_hot_list) = handle_res_json(v);

            //处理广告
            for new_ad in new_ad_list {
                if !ad_list.contains(&new_ad) {
                    ad_list.push(new_ad.clone());
                    match in_ad(&pool, &new_ad.id).await {
                        Ok(in_adtable) => {
                            if !in_adtable {
                                match add_ad(&pool, new_ad.clone()).await {
                                    Ok(_) => {
                                        info!(target:"add ad","ad_新增成功:{:?}",new_ad.key_word)
                                    }
                                    Err(e) => warn!("插入ad_table出错:{:?}", e),
                                }
                            }
                        }
                        Err(e) => warn!("数据库查询错误{:?}", e),
                    }
                }
            }
            //处理政务
            for new_gov in new_gov_list {
                if !gov_list.contains(&new_gov) {
                    gov_list.push(new_gov.clone());
                    match in_gov(&pool, &new_gov.key_word).await {
                        Ok(in_govtable) => {
                            if !in_govtable {
                                match add_gov(&pool, new_gov.clone()).await {
                                    Ok(row) => {
                                        if row > 0 {
                                            info!(target:"add gov","新增gov成功:{:?}",new_gov.key_word)
                                        } else {
                                            warn!("新增gov失败")
                                        }
                                    }
                                    Err(e) => error!("插入gov_table出错:{:?}", e),
                                }
                            }
                        }
                        Err(e) => error!("数据库查询出错:{:?}", e),
                    }
                }
            }

            //处理热搜
            //插入的
            let mut to_insert = vec![];
            //消退的
            let mut to_updata = vec![];

            {
                // let mut arc_hot_list = arc_hot_list.lock().unwrap();
                for new_hot in new_hot_list.clone() {
                    //判断是否存在
                    let mut in_hot_list: bool = false;
                    for (_, old_hot) in hot_list.iter_mut().enumerate() {
                        if old_hot.key_word == new_hot.key_word {
                            in_hot_list = true;
                            //更新相关字段
                            old_hot.updata(&new_hot);
                            // to_insert_or_update.push(old_hot.clone());
                            //更新数据库，这里不更新
                            break;
                        }
                    }
                    if !in_hot_list {
                        hot_list.push(new_hot.clone());
                        to_insert.push(new_hot.clone());
                        //不存在插入数据库
                    }
                }
                // 删除不在current_hot_list中的项，更新到列表
                hot_list.retain(|hot_item| {
                    if new_hot_list.contains(hot_item) {
                        true
                    } else {
                        info!(
                            "消退hot:key_word{},pos:{},hot:{}",
                            hot_item.key_word, hot_item.realpos, hot_item.raw_hot
                        );
                        to_updata.push(hot_item.clone());
                        false
                    }
                });
            }
            //执行数据库插入
            for hot in to_insert {
                match in_hot(&pool, &hot.key_word).await {
                    Ok(in_hottable) => {
                        if !in_hottable {
                            match add_hot(&pool, hot.clone()).await {
                                Ok(rows) => {
                                    if rows > 0 {
                                        debug!(target:"add hot","新增成功hot,key_word:{},realpos:{},raw_hot:{}",hot.key_word,hot.realpos,hot.raw_hot)
                                    }
                                }
                                Err(e) => error!("新增失败hot:{:?}", e),
                            }
                        }
                    }
                    Err(e) => error!("查询hot_table出错:{:?}", e),
                }
            }
            //执行更新
            for hot in to_updata {
                match in_hot(&pool, &hot.key_word).await {
                    Ok(in_hottable) => {
                        if in_hottable {
                            match updata_hot(&pool, &hot.clone()).await {
                                Ok(_) => {
                                    info!(target:"outhot","消退:hot更新成功:{},{},{}",hot.key_word,hot.raw_hot,hot.realpos)
                                }
                                Err(e) => warn!("更新 hot_table 出错:{:?}", e),
                            }
                        }
                    }
                    Err(e) => warn!("查询hot_table出错:{:?}", e),
                }
            }
            {
                ad_count += 1;
                hot_count += 1;
                gov_count += 1;
            }
            if gov_count >= gov_count_max {
                gov_count = 0;
                gov_list.clear();
                info!(target:"clean gov","强制刷新gov")
            }
            //todo:每1个小时删除时间过期的广告，每20秒请求一次，一个1*60*60/20=180;
            if ad_count >= ad_count_max {
                let timestamp: i64 = get_current_timestamp();
                ad_count = 0;
                ad_list.retain(|ad| ad.end_time < timestamp);
                info!(target:"clean hot","删除过期ad")
            }
            //todo:每10分钟更新一次热搜，10*60/20=30
            if hot_count >= hot_count_max {
                hot_count = 0;
                info!("每10min更新一次");
                for (_index, hot) in hot_list.clone().iter().enumerate() {
                    match in_hot(&pool, &hot.key_word).await {
                        Ok(in_hottable) => {
                            if in_hottable {
                                match updata_hot(&pool, &hot.clone()).await {
                                    Ok(rows) => {
                                        if rows > 0 {
                                            debug!(target:"updata hot","每10min:更新成功hot{:?}",hot)
                                        }
                                    }
                                    Err(_e) => warn!("更新失败hot"),
                                }
                            }
                        }
                        Err(e) => error!("查询hot_table出错:{:?}", e),
                    }
                }
            }
        }
    });

    // Task to clean old logs
    tokio::spawn(async move {
        info!(target:"clean log","清理过期log");
        let mut interval = interval(log_cleaning_interval);
        loop {
            interval.tick().await;
            clean_old_logs(log_dir, max_age_days).await;
        }
    });
}
